package com.xhwl.centiotdata.suppliersystem.mili;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.pojo.constant.MiLiConstant;
import com.xhwl.centiotdata.pojo.dto.mili.FrameMiLiDTO;
import com.xhwl.centiotdata.pojo.dto.mili.LoginMiLiDTO;
import com.xhwl.centiotdata.pojo.dto.visitor.VisitorIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IOrganizationService;
import com.xhwl.centiotdata.service.cent.IResidentInfoService;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.dto.cent.visitor.VisitorAuthDTO;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.Organization;
import com.xhwl.common.pojo.cent.sdata.Room;
import com.xhwl.common.query.cent.sdata.RoomQuery;
import com.xhwl.common.utils.ChkUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: wuyuhao
 * @createDate: 2022/10/26 19:04
 */
@Slf4j
@Service
public class VisitorMiLiHandler {

    @Autowired
    private GeneralMiLiHandler generalMiLiHandler;

    @Autowired
    private IOrganizationService iOrganizationService;

    @Autowired
    private IResidentInfoService iResidentInfoService;

    @Autowired
    private RedisUtils redisUtils;

    public void visitorAdd(VisitorIntegrationConfigDTO configDTO, Map<String, Object> map) {
        LoginMiLiDTO loginInfo = generalMiLiHandler.getLoginInfo(configDTO.getLoginName(),
                configDTO.getPassword(), configDTO.getIpAndPort());
        JSONObject req = new JSONObject(map);
        String response = generalMiLiHandler.doBusinessRequest(configDTO.getLoginName(), loginInfo,
                configDTO.getIpAndPort(), MiLiConstant.VISITOR_ADD_URL, req);
        JSONObject res = JSON.parseObject(response);
        if (res.getInteger("Result") != 0) {
            log.error("请求url: {}, errMsg: {}", MiLiConstant.VISITOR_ADD_URL, res.getString("Message"));
            throw new BusinessException(res.getString("Message"));
        }
    }

    public void visitorSignOut(VisitorIntegrationConfigDTO configDTO, Map<String, Object> map) {
        LoginMiLiDTO loginInfo = generalMiLiHandler.getLoginInfo(configDTO.getLoginName(),
                configDTO.getPassword(), configDTO.getIpAndPort());
        JSONObject req = new JSONObject(map);
        String response = generalMiLiHandler.doBusinessRequest(configDTO.getLoginName(), loginInfo,
                configDTO.getIpAndPort(), MiLiConstant.VISITOR_SIGN_OUT_URL, req);
        JSONObject res = JSON.parseObject(response);
        if (res.getInteger("Result") != 0) {
            log.error("请求url: {}, errMsg: {}", MiLiConstant.VISITOR_SIGN_OUT_URL, res.getString("Message"));
            throw new BusinessException(res.getString("Message"));
        }
    }

    public ResultJson getQrCode(VisitorIntegrationConfigDTO configDTO, VisitorAuthDTO visitorAuthDTO) {
        LoginMiLiDTO loginInfo = generalMiLiHandler.getLoginInfo(configDTO.getLoginName(),
                configDTO.getPassword(), configDTO.getIpAndPort());

        // 查询社区框架号
        String communityId = queryFrameNo(configDTO, loginInfo);

        // 查询被访人房号
        String frameNo = queryUserInfo(configDTO, visitorAuthDTO);
        if(frameNo == null) {
            return ResultJson.fail("该住户没有绑定房屋，无法获取二维码");
        }

        // 获取二维码
        String url = "https://yun.miligc.com/qrcode-generate/1.0/getqrcode";
        String timestamp = String.valueOf(System.currentTimeMillis()/1000);
        String appSecret = configDTO.getSk();
        String appId = configDTO.getAk();
        String verify = MD5.create().digestHex(timestamp + "|" + 3 + "|" + appSecret);
        String authorization = appId + ":" + timestamp + ":" + verify + ":" + ":" + 3;

        Map<String, Object> map = new HashMap<>();
        // 社区号+房号，例如：1-01010102
        map.put("userRoom", communityId + "-" + frameNo);
        map.put("beginTime", DateUtil.formatDateTime(visitorAuthDTO.getAuthStartTime()));
        map.put("endTime", DateUtil.formatDateTime(visitorAuthDTO.getAuthEndTime()));
        map.put("times", visitorAuthDTO.getTimes());
        map.put("userName", visitorAuthDTO.getName());

        String result = HttpRequest.post(url)
                .header("Authorization", "Basic " + Base64.encode(authorization))
                .header("Content-Type", "multipart/form-data")
                .form(map)
                .execute()
                .body();
        JSONObject str = JSON.parseObject(result);
        if(Integer.valueOf(1).equals(str.getInteger("errorCode"))) {
            Object qrcode = str.getJSONObject("body").get("qrcode");
            redisUtils.setWithMinute(String.format(MiLiConstant.VISITOR_QRCODE_KEY, visitorAuthDTO.getId()), qrcode, 10);
            return ResultJson.success(qrcode);
        } else {
            log.error("获取二维码错误： {}", str.get("errorMsg"));
            throw new BusinessException();
        }
    }

    private String queryFrameNo(VisitorIntegrationConfigDTO configDTO, LoginMiLiDTO loginInfo) {
        // 查询社区框架号
        String response = generalMiLiHandler.doBusinessRequest(configDTO.getLoginName(), loginInfo,
                configDTO.getIpAndPort(), MiLiConstant.FRAME_QUERY_URL, new JSONObject());
        log.info("queryFrame->response: {}", response);
        // 解析返回的设备列表数据
        JSONObject jsonObject = JSON.parseObject(response);
        JSONArray body = jsonObject.getJSONArray("Body");
        List<FrameMiLiDTO> frameMiLiDTOList = body.toJavaList(FrameMiLiDTO.class);
        if(ChkUtil.isNull(frameMiLiDTOList)) {
            log.error("社区为空： {}", body);
            throw new BusinessException();
        }
        FrameMiLiDTO frameMiLiDTO = frameMiLiDTOList.get(0);
        return frameMiLiDTO.getFrameNo();
    }

    private String queryUserInfo(VisitorIntegrationConfigDTO configDTO, VisitorAuthDTO visitorAuthDTO) {
        if(ChkUtil.isNull(visitorAuthDTO.getIntervieweeOpenId())) {
            log.error("被访人不存在：{}", visitorAuthDTO);
            throw new BusinessException();
        }
        String accountId = String.valueOf(visitorAuthDTO.getIntervieweeId());
        List<Organization> organizationList = iResidentInfoService.getOrgListByAccountId(accountId, configDTO.getProjectId());
        StringBuilder frameNo = new StringBuilder();
        if(ChkUtil.isNotNull(organizationList)) {
            List<Integer> orgIdList = organizationList.stream().map(Organization::getId).collect(Collectors.toList());
            RoomQuery roomQuery = new RoomQuery();
            roomQuery.setOrgIds(orgIdList);
            roomQuery.setProjectId(configDTO.getProjectId());
            List<Room> roomList = iOrganizationService.list(roomQuery);
            List<String> roomCode = roomList.stream().map(Room::getCode).collect(Collectors.toList());
            Map<String, String> codeMap = new HashMap<>();
            for(String code : roomCode) {
                String pre = code.substring(0, 4);
                String tail = code.substring(4);
                if(codeMap.get(pre) == null) {
                    codeMap.put(pre, tail);
                } else {
                    codeMap.put(pre, codeMap.get(pre) + "," + tail);
                }
            }
            for(Map.Entry entry : codeMap.entrySet()) {
                frameNo.append(entry.getKey()).append(entry.getValue()).append("&");
            }
            return frameNo.substring(0, frameNo.length() - 1);
        }
        return null;
    }
}
